package com.squareshoot.picCheckin;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Message;
import android.provider.Settings;
import android.util.Log;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

public class ChooseVenue extends Activity{
	private static final int GROUP1 = 111;
	private static final int ID_REFRESH = 1111;
	private static final int ID_ADD = 1114;
	private static final int ID_SEARCH = 1112;
	protected static final int VENUEDETAILS = 0;

	String username;
	String password;
	String nomPrenom = null;
	String picuserid,fsid;
	boolean sendtotwitter,sendtofacebook;
	double latitude,longitude;
	ArrayList<String> venues; 
	LocationManager lm;
	LocationListener listenerNetwork;
	LocationListener listenerGps;
	TextView positionText;
	TextView countryText;
	TextView cityText;
	TextView title;
	ProgressBar progressLoading;
	private ProfileDb mDbHelper;
	Runnable updateAdapter=null;
	boolean venuesUpdatable;
	Uri photo;
	boolean photoSelected=false;
	Bitmap bm;
	private GetVenuesTask venuesTask;
	private Address adresse=null;

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.choosevenue);
		if(Common.HIGHDEBUG)
			Log.d(Common.TAG,"onCreate : ChooseVenue");

		getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.customtitle);
		setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);

		progressLoading = (ProgressBar)findViewById(R.id.indeterminateProgressBar);
		progressLoading.setVisibility(View.GONE);

		if(lm==null)
			lm= (LocationManager)getSystemService(Context.LOCATION_SERVICE);

		venuesUpdatable = true;

		positionText = (TextView)findViewById(R.id.locationText);
		countryText = (TextView)findViewById(R.id.countryText);
		cityText = (TextView)findViewById(R.id.cityText);
		title = (TextView)findViewById(R.id.titleText);

		Bundle bundle = this.getIntent().getExtras();
		String userProfile = bundle.getString("user");
		username = bundle.getString("username");
		password = bundle.getString("password");
		sendtotwitter = bundle.getBoolean("sendtotwitter");
		sendtofacebook = bundle.getBoolean("sendtofacebook");
		
		if(bundle.containsKey("photo")){
			photo = (Uri)bundle.get("photo");
			photoSelected = true;
		}

		String photoURL = null;
		try {
			JSONObject jUser=new JSONObject(userProfile);
			nomPrenom=jUser.getString("firstname");
			picuserid = jUser.getString("picuserid");
			fsid = jUser.getString("id");
			if(jUser.has("lastname")){
				nomPrenom += " "+jUser.getString("lastname");
			}
			photoURL = jUser.getString("photo");
		} catch (JSONException e) {
			if(Common.HIGHDEBUG)
				Log.e(Common.TAG,"ChooseVenue : "+e.getMessage());
		}

		//Affichage du nom, prenom et de la photo de profil
		TextView tvName = (TextView)findViewById(R.id.profileName);
		ImageView ivPhoto = (ImageView)findViewById(R.id.profilePic);
		tvName.setText(nomPrenom);

		//telecharge la photo et la stocke sur la SD, ou la prend direct sur la sd si elle existe
		bm = Common.getCachedPicture(photoURL);
		ivPhoto.setImageBitmap(Common.getRoundedCornerBitmap(bm));
		//On start l'Activity MyProfile si on clique sur sa photo
//		ivPhoto.setOnClickListener(new OnClickListener() {
//			public void onClick(View v) {
//				startFriendsAndPhotos();
//			}
//		});

		if(savedInstanceState==null){
			if(Common.HIGHDEBUG)
				Log.i(Common.TAG,"Venues vide : recup position");
			//On recupere la position de l'utilisateur
			registerLocationListeners();
		}
		else{
			if(Common.HIGHDEBUG){
				Log.i(Common.TAG,"saveInstantestate pas vide");
				Log.i(Common.TAG,savedInstanceState.getString("position"));
			}
			adresse=savedInstanceState.getParcelable("adresse");
			if(adresse!=null){
				countryText.setText(adresse.getCountryName());
				cityText.setText(adresse.getLocality());
			}
			positionText.setText(savedInstanceState.getString("position"));

			latitude=savedInstanceState.getDouble("latitude");
			longitude=savedInstanceState.getDouble("longitude");
			if(savedInstanceState.getStringArrayList("venues")!=null){
				if(Common.HIGHDEBUG)
					Log.i(Common.TAG,savedInstanceState.getStringArrayList("venues").toString());
				venues=savedInstanceState.getStringArrayList("venues");
				setAdapter();
			}
			else{
				if(Common.HIGHDEBUG)
					Log.i(Common.TAG,"les venues sont vides");
			}
			if(getLastNonConfigurationInstance()!=null){
				if(Common.HIGHDEBUG)
					Log.i(Common.TAG,"recup venueTask");
				progressLoading.setVisibility(View.VISIBLE);
				venuesTask=(GetVenuesTask) getLastNonConfigurationInstance();
				venuesTask.setActivity(this);
			}
		}

		//pour test on lit le cookie dans la base
		mDbHelper = new ProfileDb(this);
		mDbHelper.open();
		Cursor c = mDbHelper.recupCookie(username);
		startManagingCursor(c);
		//		if(Common.HIGHDEBUG)
		//			Log.i(Common.TAG,"cookie recup :"+c.getString(c.getColumnIndexOrThrow(ProfileDb.KEY_COOKIE)));
		mDbHelper.close();
		c.close();
		if(Common.HIGHDEBUG)
			Log.i(Common.TAG,"onCreate:ChooseVenue:done");
	}

	@Override
	public void onResume(){
		if(Common.HIGHDEBUG)
			Log.i(Common.TAG,"ChooseVenue : onResume");
		//		registerLocationListener();
		if(lm==null)
			lm= (LocationManager)getSystemService(Context.LOCATION_SERVICE);
		super.onResume();
	}

	@Override
	public void onPause(){
		if(Common.HIGHDEBUG)
			Log.i(Common.TAG,"ChooseVenue : onPause");
		try{
			lm.removeUpdates(listenerGps);
			if(Common.HIGHDEBUG)
				Log.d(Common.TAG,"Removed listener GPS");
		}catch(IllegalArgumentException e){
			if(Common.HIGHDEBUG)
				Log.d(Common.TAG,"listener GPS is null");
		}
		try{
			lm.removeUpdates(listenerNetwork);
			if(Common.HIGHDEBUG)
				Log.d(Common.TAG,"Removed listener Network");
		}catch(IllegalArgumentException e){
			if(Common.HIGHDEBUG)
				Log.d(Common.TAG,"listener Network is null");
		}
		lm=null;
		super.onPause();
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		if(Common.HIGHDEBUG)
			Log.i(Common.TAG,"ChooseVenue : onSaveInstantState");
		outState.putStringArrayList("venues",venues);
		outState.putParcelable("adresse",adresse);
		outState.putString("position", positionText.getText().toString());
		outState.putDouble("latitude",latitude);
		outState.putDouble("longitude",longitude);
	}

	public Object onRetainNonConfigurationInstance() {
		if(venuesTask!=null){
			venuesTask.setActivity(null);
		}
		return venuesTask;
	}

	//Recupere les venues pres de l'utilisateur
	private void updateVenues(double longitude, double latitude){
		this.latitude = latitude;
		this.longitude = longitude;
		venuesUpdatable = false;

		//Recupere l'adresse. Ne fonctionne pas dans l'emulateur
		ArrayList<Address> addresses = new ArrayList<Address>();
		Geocoder myLocation = new Geocoder(getApplicationContext(),Locale.getDefault());   
		try {
			addresses = (ArrayList<Address>) myLocation.getFromLocation(latitude,longitude, 1);
		} catch (IOException e1) {
			Log.d(Common.TAG,"Impossible de trouver l'adresse :(");
		}

		//Affichage de l'adresse, ville, etc...
		positionText.setText(latitude+" "+longitude);
		if(addresses.size()>0){
			adresse = addresses.get(0);
			positionText.setText(adresse.getAddressLine(0));
			cityText.setText(adresse.getLocality());
			countryText.setText(adresse.getCountryName());
		}else{
			cityText.setText("");
			countryText.setText("");
		}
		//Une fois positionne, on telecharge les venues autour
		venuesTask=new GetVenuesTask();
		venuesTask.setActivity(this);
		venuesTask.execute();
	}

	//On set l'adapter sur la liste, ainsi que le onClickListener
	private void setAdapter(){
		ListView listVenues = (ListView)findViewById(R.id.listVenues); 
		VenuesListAdapter adapter = new VenuesListAdapter(this,venues);
		listVenues.setAdapter(adapter);
		setOnClick(listVenues);
	}

	//ClickListener de la liste des venues
	private void setOnClick(ListView listVenues){
		listVenues.setOnItemClickListener(new OnItemClickListener() {
			public void onItemClick(AdapterView<?> arg0, View view, int position,long id) {
				String venue = venues.get(position);
				String venueId = null;
				try {
					JSONObject jVenue = new JSONObject(venue);
					venueId = jVenue.getString("id");
				}catch(JSONException e){
					e.printStackTrace();
				}
				startVenueDetails(venueId);
			}
		});
	}

	//Prend la reponse de Foursquare, et rempli un ArrayList avec les venues
	public static ArrayList<String> fillVenuesArray(String reponse){
		ArrayList<String> venuesArray = new ArrayList<String>();

		try {
			JSONObject jResult=new JSONObject(reponse);
			JSONArray jVenuesGroups = jResult.getJSONArray("groups");

			for(int i=0;i<jVenuesGroups.length();i++){
				String group = jVenuesGroups.getJSONObject(i).getString("type");
				JSONObject jNearby = jVenuesGroups.getJSONObject(i);
				JSONArray jNear = jNearby.getJSONArray("venues");
				for(int j=0;j<jNear.length();j++){
					JSONObject jEndroit=jNear.getJSONObject(j);
					if(j==0) jEndroit.put("jVenueGroup",group);
					venuesArray.add(jEndroit.toString());
				}
			}
		} catch (JSONException e) {
			e.printStackTrace();
		}
		return venuesArray;
	}

	//Activation des location listener
	private void registerLocationListeners(){
		//		Criteria criteria = new Criteria();
		//		criteria.setAccuracy(Criteria.ACCURACY_FINE);
		List <String> listProviders = lm.getProviders(true);
		int providersCount = listProviders.size();
		if(Common.HIGHDEBUG)
			Log.d(Common.TAG,"Providers : "+listProviders.toString()+ "count : "+ providersCount);
		if(providersCount==0 || (providersCount==1 && listProviders.get(0).compareTo("passive")==0)){
			Toast erreurToast = Toast.makeText(ChooseVenue.this,getString(R.string.noLocationProvider),Toast.LENGTH_LONG);
			erreurToast.setGravity(Gravity.CENTER, 0, 0);
			erreurToast.show();
			startActivity(new Intent(Settings.ACTION_SECURITY_SETTINGS));
			finish();
		}else{
			for(int i=0;i<providersCount;i++){
				String provider = (String)listProviders.get(i);
				if(provider.compareTo(LocationManager.GPS_PROVIDER)==0){
					if(listenerGps==null){
						if(Common.HIGHDEBUG)
							Log.d(Common.TAG,"Creating Location Listener for GPS");
						listenerGps = createLocationListener(provider);
					}else{
						if(Common.HIGHDEBUG)
							Log.d(Common.TAG,"listenerGPS already exists");
					}
					lm.requestLocationUpdates(provider,200, 0,listenerGps);
				}else if(provider.compareTo(LocationManager.NETWORK_PROVIDER)==0){
					if(listenerNetwork==null){
						if(Common.HIGHDEBUG)
							Log.d(Common.TAG,"Creating Location Listener Network");
						listenerNetwork = createLocationListener(provider);
					}else{
						if(Common.HIGHDEBUG)
							Log.d(Common.TAG,"listener Network already exists");
					}
					Location l=lm.getLastKnownLocation(provider);
					if(l!=null && venuesUpdatable){
						updateVenues(l.getLongitude(),l.getLatitude());
						if(Common.DEBUG)
							Log.d(Common.TAG,"Got last location");
					}
					lm.requestLocationUpdates(provider, 0, 0,listenerNetwork);
				}
			}
		}
	}

	//Creation des location listener
	private LocationListener createLocationListener(final String provider){
		LocationListener l = new LocationListener() {
			public void onStatusChanged(String provider, int status, Bundle extras) {
			}
			public void onProviderEnabled(String provider) {
			}
			public void onProviderDisabled(String provider) {
			}
			public void onLocationChanged(Location location) {
				if(Common.DEBUG)
					Log.d(Common.TAG,"provider "+provider+" : location changed : "+location.getLatitude()+" "+location.getLongitude());
				if(venuesUpdatable){
					lm.removeUpdates(this);
					updateVenues(location.getLongitude(), location.getLatitude());
				}
			}
		};
		return l;
	}

	/*
	 * Creation du menu
	 * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)
	 */
	public boolean onCreateOptionsMenu(Menu menu) {
		menu.add(GROUP1, ID_REFRESH, 0, getString(R.string.refresh)).setIcon(R.drawable.ic_menu_refresh);
		menu.add(GROUP1,ID_ADD,1, getString(R.string.addVenueButton)).setIcon(R.drawable.ic_menu_add);
		menu.add(GROUP1,ID_SEARCH,1, getString(R.string.search)).setIcon(R.drawable.ic_menu_search);
		return true;
	}

	/*
	 * Ecouteur du menu
	 * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
	 */
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case ID_REFRESH:
			if(Common.HIGHDEBUG)
				Log.i(Common.TAG,"Refresh Position");
			registerLocationListeners();
			return true;
		case ID_SEARCH:
			onSearchRequested();
			return true;
		case ID_ADD:
			startAddVenue();
			return true;
		}
		return false;
	}

	//En cas d'appui sur la touche "loupe"
	public boolean onSearchRequested() {
		Bundle appData = new Bundle();
		appData.putDouble("latitude",latitude);
		appData.putDouble("longitude",longitude);
		appData.putString("username",username);
		appData.putString("password",password);
		appData.putBoolean("sendtotwitter", sendtotwitter);
		appData.putBoolean("sendtofacebook", sendtofacebook);
		if(photoSelected)
			appData.putParcelable("photo",photo);
		startSearch(null, false, appData, false);
		return true;
	}

	private void startVenueDetails(String venueId){
		Intent i=new Intent(ChooseVenue.this,VenueDetails.class);
		Bundle bundle = new Bundle();
		bundle.putString("venueId",venueId);
		bundle.putString("username",username);
		bundle.putString("password",password);
		bundle.putDouble("latitude",latitude);
		bundle.putDouble("longitude",longitude);
		bundle.putBoolean("sendtotwitter",sendtotwitter);
		bundle.putBoolean("sendtofacebook",sendtofacebook);
		if(photoSelected)
			bundle.putParcelable("photo",photo);
		i.putExtras(bundle);
		startActivityForResult(i,VENUEDETAILS);
	}

	private void startAddVenue(){
		Intent i=new Intent(ChooseVenue.this,AddVenue.class);
		Bundle bundle = new Bundle();
		bundle.putString("username",username);
		bundle.putString("password",password);
		bundle.putDouble("latitude",latitude);
		bundle.putDouble("longitude",longitude);
		bundle.putBoolean("sendtotwitter",sendtotwitter);
		bundle.putBoolean("sendtofacebook",sendtofacebook);
		if(adresse!=null)
			bundle.putParcelable("adresse",adresse);
		if(photoSelected)
			bundle.putParcelable("photo",photo);
		i.putExtras(bundle);
		startActivity(i);
	}

	private void onThreadCompleted(Bundle data){
		if(!data.containsKey("eMessage")){
			venues = ChooseVenue.fillVenuesArray(data.getString("reponse"));
			setAdapter();
		}else{
			Log.e(Common.TAG,"ChooseVenue, Exception : "+data.getString("eMessage"));
			//Erreur de type IOException dans la thread GetVenues
			Toast erreurToast = Toast.makeText(ChooseVenue.this,data.getString("eMessage"),Toast.LENGTH_SHORT);
			erreurToast.setGravity(Gravity.CENTER, 0, 0);
			erreurToast.show();
		}
		venuesUpdatable = true;
	}

	private class GetVenuesTask extends AsyncTask<String,String,Message>{
		private ChooseVenue activity;
		private boolean completed=false;
		private Message msg;

		protected void onPreExecute() {
			activity.progressLoading.setVisibility(View.VISIBLE);
			msg = Message.obtain();
		}

		@Override
		protected Message doInBackground(String... params) {
			Bundle data = new Bundle();
			try{
				String venuesUrl = "http://api.foursquare.com/v1/venues.json?l=30&geolat="+latitude+"&geolong="+longitude;
				String reponse = Common.getUrlDataAuth(venuesUrl,username,password);	
				data.putString("reponse",reponse);
			}catch (IOException e) {
				data.putString("eMessage",e.getMessage());
			}
			msg.setData(data);
			return msg;
		}

		@Override
		protected void onPostExecute(Message msg) {
			completed=true;
			if(activity!=null)
				endTask(msg);
		}

		private void setActivity(ChooseVenue activity) {
			this.activity = activity;
			if ( completed ) {
				endTask(msg);
			}
		}

		private void endTask(Message msg){
			activity.venuesTask=null;
			activity.progressLoading.setVisibility(View.GONE);
			activity.onThreadCompleted(msg.getData());
		}
	}
}
